// Chat reaction handling

const upArrowString = '⮝';
const downArrowString = '⮟';

function getServerURL() {
    var serverURL = '';
    if(app  && typeof app == 'object' && (app?.getSetting || false) && typeof app.getSetting === 'function') {
        serverURL = app.getSetting('server_url') || '';
        if(serverURL.endsWith('/')) serverURL = serverURL.slice(0, -1);
    }
    return serverURL;
}

async function loadReactions(chatId) {
    try {
        const response = await fetch(`${getServerURL()}/api/chats/${chatId}/reactions`);
        const data = await response.json();

        if (data.ok) {
            return {
                reactions: data.reactions,
                userReactions: data.user_reactions
            };
        }
        return null;
    } catch (error) {
        console.error('Error loading reactions:', error);
        return null;
    }
}

async function loadBatchedReactions() {
    try {
        const containers = document.querySelectorAll('.reaction-container[data-chat-id]');
        if (!containers || containers.length === 0) {
            return;
        }

        const chatIds = Array.from(containers).map(c => c.dataset.chatId).filter(id => id);
        const uniqueChatIds = [...new Set(chatIds)];

        if (uniqueChatIds.length === 0) {
            return;
        }

        const chatIdsParam = uniqueChatIds.join(',');
        const response = await fetch(`${getServerURL()}/api/batched-reactions?chat_ids=${encodeURIComponent(chatIdsParam)}`);
        const data = await response.json();

        if (data.ok && data.reactions) {
            for (const [chatId, reactionData] of Object.entries(data.reactions)) {
                updateReactionDisplay(
                    parseInt(chatId),
                    reactionData.reactions,
                    reactionData.user_reactions
                );
            }
        }
    } catch (error) {
        console.error('Error loading batched reactions:', error);
    }
}

async function addReaction(chatId, reactionType, emojiValue = null) {
    try {
        const payload = {
            reaction_type: reactionType
        };

        if (reactionType === 'emoji' && emojiValue) {
            payload.emoji_value = emojiValue;
        }

        const response = await fetch(`${getServerURL()}/api/chats/${chatId}/react`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            credentials: 'include',
            body: JSON.stringify(payload)
        });

        const data = await response.json();
        return data.ok;
    } catch (error) {
        console.error('Error adding reaction:', error);
        return false;
    }
}

async function removeReaction(chatId, reactionType) {
    try {
        const response = await fetch(`${getServerURL()}/api/chats/${chatId}/react`, {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json'
            },
            credentials: 'include',
            body: JSON.stringify({
                reaction_type: reactionType
            })
        });

        const data = await response.json();
        return data.ok;
    } catch (error) {
        console.error('Error removing reaction:', error);
        return false;
    }
}

function updateReactionDisplay(chatId, reactions, userReactions) {
    // Find ALL containers for this chatId (handles duplicate threads on same page)
    const containers = document.querySelectorAll(`.reaction-container[data-chat-id="${chatId}"]`);
    if (!containers || containers.length === 0) return;

    // Update each instance of the thread
    containers.forEach(container => {
        updateSingleReactionContainer(container, chatId, reactions, userReactions);
    });
}

function updateSingleReactionContainer(container, chatId, reactions, userReactions) {
    // Store user reaction state in dataset
    if (userReactions) {
        container.dataset.userLiked = userReactions.like ? 'true' : 'false';
        container.dataset.userDisliked = userReactions.dislike ? 'true' : 'false';
        container.dataset.userEmoji = userReactions.emoji || '';
    }

    let html = '';

    // Like button
    const likeCount = reactions.likes || 0;
    const likeActive = container.dataset.userLiked === 'true';
    html += `<button class="btn btn-sm btn-outline-secondary ${likeActive ? '' : 'text-muted'} reaction-btn" 
                     data-reaction="like" data-chat-id="${chatId}">
                ${upArrowString} ${likeCount}
             </button>`;

    // Dislike button
    const dislikeCount = reactions.dislikes || 0;
    const dislikeActive = container.dataset.userDisliked === 'true';
    html += `<button class="btn btn-sm btn-outline-secondary ${dislikeActive ? '' : 'text-muted'} reaction-btn" 
                     data-reaction="dislike" data-chat-id="${chatId}">
                ${downArrowString} ${dislikeCount}
             </button>`;

    // Emoji reactions
    if (reactions.emojis && Object.keys(reactions.emojis).length > 0) {
        const emojiEntries = Object.entries(reactions.emojis);
        const maxDisplayEmojis = 5;

        for (let i = 0; i < Math.min(maxDisplayEmojis, emojiEntries.length); i++) {
            const [emoji, count] = emojiEntries[i];
            html += `<span class="badge bg-secondary emoji-reaction" data-emoji="${emoji}">
                        ${emoji} ${count}
                     </span>`;
        }

        // Show overflow button if there are more emojis
        if (emojiEntries.length > maxDisplayEmojis) {
            const remaining = emojiEntries.length - maxDisplayEmojis;
            html += `<button class="btn btn-sm btn-outline-secondary" 
                             data-chat-id="${chatId}" 
                             data-action="show-more-emojis">
                        +${remaining} more
                     </button>`;
        }
    }

    // Add emoji button
    html += `<button class="btn btn-sm btn-outline-secondary" 
                     data-chat-id="${chatId}" 
                     data-action="add-emoji">
                ➕
             </button>`;

    container.innerHTML = html;

    // Attach event listeners
    attachReactionListeners(container, chatId);
}

function attachReactionListeners(container, chatId) {
    // Like/Dislike buttons
    container.querySelectorAll('.reaction-btn').forEach(btn => {
        btn.addEventListener('click', async (e) => {
            e.preventDefault();
            const reactionType = btn.dataset.reaction;
            const isActive = !btn.classList.contains('text-muted');

            // Get current state from ALL containers for this chat
            const allContainers = document.querySelectorAll(`.reaction-container[data-chat-id="${chatId}"]`);
            const firstContainer = allContainers[0];
            
            if (isActive) {
                // User is removing their reaction
                // Optimistically update all instances
                allContainers.forEach(c => {
                    const targetBtn = c.querySelector(`.reaction-btn[data-reaction="${reactionType}"]`);
                    if (targetBtn) {
                        targetBtn.classList.add('text-muted');
                        const currentText = targetBtn.textContent.trim();
                        const match = currentText.match(/\d+/);
                        if (match) {
                            const currentCount = parseInt(match[0]);
                            const newCount = Math.max(0, currentCount - 1);
                            targetBtn.innerHTML = `${reactionType === 'like' ? upArrowString : downArrowString} ${newCount}`;
                        }
                    }
                    c.dataset[`user${reactionType.charAt(0).toUpperCase() + reactionType.slice(1)}d`] = 'false';
                });

                // Send to server and reconcile if failed
                const success = await removeReaction(chatId, reactionType);
                if (!success) {
                    const data = await loadReactions(chatId);
                    if (data) {
                        updateReactionDisplay(chatId, data.reactions, data.userReactions);
                    }
                }
            } else {
                // User is adding their reaction
                const oppositeType = reactionType === 'like' ? 'dislike' : 'like';
                
                // Check if opposite reaction is active
                const oppositeBtn = firstContainer.querySelector(`.reaction-btn[data-reaction="${oppositeType}"]`);
                const oppositeActive = oppositeBtn && !oppositeBtn.classList.contains('text-muted');

                // Optimistically update all instances
                allContainers.forEach(c => {
                    // Remove opposite reaction if active
                    if (oppositeActive) {
                        const oppBtn = c.querySelector(`.reaction-btn[data-reaction="${oppositeType}"]`);
                        if (oppBtn) {
                            oppBtn.classList.add('text-muted');
                            const oppositeText = oppBtn.textContent.trim();
                            const oppositeMatch = oppositeText.match(/\d+/);
                            if (oppositeMatch) {
                                const oppositeCount = parseInt(oppositeMatch[0]);
                                const newOppositeCount = Math.max(0, oppositeCount - 1);
                                oppBtn.innerHTML = `${oppositeType === 'like' ? upArrowString : downArrowString} ${newOppositeCount}`;
                            }
                        }
                        c.dataset[`user${oppositeType.charAt(0).toUpperCase() + oppositeType.slice(1)}d`] = 'false';
                    }

                    // Add the new reaction
                    const targetBtn = c.querySelector(`.reaction-btn[data-reaction="${reactionType}"]`);
                    if (targetBtn) {
                        targetBtn.classList.remove('text-muted');
                        const currentText = targetBtn.textContent.trim();
                        const match = currentText.match(/\d+/);
                        const currentCount = match ? parseInt(match[0]) : 0;
                        const newCount = currentCount + 1;
                        targetBtn.innerHTML = `${reactionType === 'like' ? upArrowString : downArrowString} ${newCount}`;
                    }
                    c.dataset[`user${reactionType.charAt(0).toUpperCase() + reactionType.slice(1)}d`] = 'true';
                });

                // Send to server and reconcile if failed
                const success = await addReaction(chatId, reactionType);
                if (!success) {
                    const data = await loadReactions(chatId);
                    if (data) {
                        updateReactionDisplay(chatId, data.reactions, data.userReactions);
                    }
                }
            }
        });
    });

    // Add emoji button
    const addEmojiBtn = container.querySelector('[data-action="add-emoji"]');
    if (addEmojiBtn) {
        addEmojiBtn.addEventListener('click', (e) => {
            e.preventDefault();
            showEmojiPicker(chatId);
        });
    }

    // Show more emojis button
    const showMoreBtn = container.querySelector('[data-action="show-more-emojis"]');
    if (showMoreBtn) {
        showMoreBtn.addEventListener('click', (e) => {
            e.preventDefault();
            showAllEmojis(chatId);
        });
    }
}

function showEmojiPicker(chatId) {
    const commonEmojis = [
        // Smileys
        '😀', '😂', '😍', '😊', '😗', '😘',
        '😎', '😜', '😷', '😇', '😈', '😺',
        '😒', '😔', '😞', '😠', '😩', '😡',
        '😱', '😴', '😢', '💀', '💋', '💘',
        '😭', '😳', '😵', '😶', '🤬', '🤯',
        '😐', '😑', '😕', '😖', '😣', '😥',
        // Symbols
        '🎉', '🔥', '💯', '❤️', '⭐', '✨',
        '💦', '💥', '💫', '🍆', '🍑', '💭',
        '💰', '💵', '💴', '💶', '💷', '🗡️',
        // Racial emojis
        '💪', '💪🏻', '💪🏼', '💪🏽', '💪🏾', '💪🏿',
        '👏', '👏🏻', '👏🏼', '👏🏽', '👏🏾', '👏🏿',
        '👋', '👋🏻', '👋🏼', '👋🏽', '👋🏾', '👋🏿',
        '👌', '👌🏻', '👌🏼', '👌🏽', '👌🏾', '👌🏿',
        '✊', '✊🏻', '✊🏼', '✊🏽', '✊🏾', '✊🏿',
        '🤛', '🤛🏻', '🤛🏼', '🤛🏽', '🤛🏾', '🤛🏿',
        '🤜', '🤜🏻', '🤜🏼', '🤜🏽', '🤜🏾', '🤜🏿',
        '🧙‍♂️', '🧙🏻‍♂️', '🧙🏼‍♂️', '🧙🏽‍♂️', '🧙🏾‍♂️', '🧙🏿‍♂️',
        '👮', '👮🏻', '👮🏼', '👮🏽', '👮🏾', '👮🏿',
        '🤴', '🤴🏻', '🤴🏼', '🤴🏽', '🤴🏾', '🤴🏿'
    ];

    // Remove existing modal if present
    const existingModal = document.getElementById('emojiPickerModal');
    if (existingModal) {
        existingModal.remove();
    }

    // Create Bootstrap modal
    const modalHtml = `
        <div class="modal fade" id="emojiPickerModal" tabindex="-1" aria-labelledby="emojiPickerModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="emojiPickerModalLabel">Choose an emoji</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <div class="emoji-grid">
                            ${commonEmojis.map(emoji =>
        `<button class="btn btn-sm btn-outline-secondary emoji-option" data-emoji="${emoji}">${emoji}</button>`
    ).join('')}
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                    </div>
                </div>
            </div>
        </div>
    `;

    document.body.insertAdjacentHTML('beforeend', modalHtml);

    const modalElement = document.getElementById('emojiPickerModal');
    const modal = new bootstrap.Modal(modalElement);

    // Emoji selection
    modalElement.querySelectorAll('.emoji-option').forEach(btn => {
        btn.addEventListener('click', async () => {
            const emoji = btn.dataset.emoji;
            modal.hide();

            // Find ALL containers for this chatId
            const containers = document.querySelectorAll(`.reaction-container[data-chat-id="${chatId}"]`);
            if (!containers || containers.length === 0) return;

            // Use first container to build current state
            const firstContainer = containers[0];
            const likeBtn = firstContainer.querySelector('.reaction-btn[data-reaction="like"]');
            const dislikeBtn = firstContainer.querySelector('.reaction-btn[data-reaction="dislike"]');
            const emojiElements = firstContainer.querySelectorAll('.emoji-reaction');

            const reactions = {
                likes: likeBtn ? (parseInt(likeBtn.textContent.match(/\d+/)?.[0]) || 0) : 0,
                dislikes: dislikeBtn ? (parseInt(dislikeBtn.textContent.match(/\d+/)?.[0]) || 0) : 0,
                emojis: {}
            };

            // Parse existing emojis
            emojiElements.forEach(el => {
                const emojiIcon = el.dataset.emoji;
                const count = parseInt(el.textContent.match(/\d+/)?.[0]) || 1;
                reactions.emojis[emojiIcon] = count;
            });

            // Add new emoji optimistically
            if (!reactions.emojis[emoji]) {
                reactions.emojis[emoji] = 0;
            }
            reactions.emojis[emoji] += 1;

            const userReactions = {
                like: firstContainer.dataset.userLiked === 'true',
                dislike: firstContainer.dataset.userDisliked === 'true',
                emoji: emoji
            };

            // Update ALL instances immediately
            updateReactionDisplay(chatId, reactions, userReactions);

            // Send to server in background
            const success = await addReaction(chatId, 'emoji', emoji);

            // Fetch fresh data to reconcile only if server request failed
            if (!success) {
                const freshData = await loadReactions(chatId);
                if (freshData) {
                    updateReactionDisplay(chatId, freshData.reactions, freshData.userReactions);
                }
            }
        });
    });

    // Clean up modal after it's hidden
    modalElement.addEventListener('hidden.bs.modal', () => {
        modalElement.remove();
    });

    // Show the modal
    modal.show();
}

async function showAllEmojis(chatId) {
    const data = await loadReactions(chatId);
    if (!data || !data.reactions || !data.reactions.emojis) return;

    const emojiEntries = Object.entries(data.reactions.emojis);

    const popup = document.createElement('div');
    popup.className = 'emoji-overflow-popup';
    popup.innerHTML = `
        <div class="card shadow">
            <div class="card-body">
                <h6 class="card-title">All emoji reactions</h6>
                <div class="emoji-list">
                    ${emojiEntries.map(([emoji, count]) =>
        `<div class="emoji-item">
                            <span class="emoji">${emoji}</span>
                            <span class="count">${count}</span>
                         </div>`
    ).join('')}
                </div>
                <button class="btn btn-sm btn-secondary mt-2 w-100" id="close-emoji-overflow">Close</button>
            </div>
        </div>
    `;

    document.body.appendChild(popup);

    // Position in center
    popup.style.position = 'fixed';
    popup.style.left = '50%';
    popup.style.top = '50%';
    popup.style.transform = 'translate(-50%, -50%)';
    popup.style.zIndex = '9999';

    // Close button
    popup.querySelector('#close-emoji-overflow').addEventListener('click', () => {
        popup.remove();
    });
}
